/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package thecliffproblem;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 *
 * @author Jaime
 */
public class Square {
    
    private static final double cliffReward = -100;
    private static final double goalReward = 0;
    private static final double movingReward = -1;
    
    // Each position of this vector contains the reward for each action
    // each position refers to the action ID equal to the index of that position
    private double[] actionEvaluation;
    private boolean cliff;
    private boolean terminal;
    private Coordinate coordinate;
    
    public Square(boolean cliff, boolean terminal, Coordinate coordinate)
    {
        assert !cliff || terminal : "When square is cliff, "
                + "it must be terminal!";
        
        actionEvaluation = new double[Action.values().length];
        this.cliff = cliff;
        this.terminal = terminal;
        this.coordinate = coordinate;
    }
    
    public Action greedlyChooseNextBestAction()
    {
        // This next line demands the number of actions to be four!
        double max = Math.max(Math.max(actionEvaluation[0], actionEvaluation[1]), 
                Math.max(actionEvaluation[2], actionEvaluation[3]));
        
        List<Action> maxValues = new ArrayList<Action>();
        
        int id = 0;
        
        for(double d:actionEvaluation)
        {
            if(d == max)
            {
                maxValues.add(Action.idToAction(id));
            }
            
            id++;
        }
        
        Random r = new Random();
        
        int chosen = r.nextInt(maxValues.size());
        
        return maxValues.get(chosen);
        
    }
    
    public double getActionEvaluation(Action action)
    {
        return actionEvaluation[action.getID()];
    }
    
    public void setActionEvaluation(Action action, double evaluation)
    {
        actionEvaluation[action.getID()] = evaluation;
    }

    /**
     * @return the cliff
     */
    public boolean isCliff() {
        return cliff;
    }

    /**
     * @return the terminal
     */
    public boolean isTerminal() {
        return terminal;
    }
    

    /**
     * @return the coordinate
     */
    public Coordinate getCoordinate() {
        return coordinate;
    }
    
    public boolean isGoal()
    {
        return !isCliff() && isTerminal();
    }
    
    public double getReward()
    {
        if(isCliff())
            return cliffReward;
        if(isGoal())
            return goalReward;
        
        return movingReward;
    }
    
    public void reset()
    {
        for(int i = 0; i < actionEvaluation.length; i++)
        {
            actionEvaluation[i] = 0;
        }
    }
    
}
